<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>index</title>
</head>
<style>
  *{
    padding: 0;
    margin: 0;
  }
  .cube{
    width: 750px;
    height: 750px;
    background:#f8f8f8;
    display: flex;
    flex-direction: column;
    border-top:1px  solid #e5e5e5;
    border-right:1px  solid #e5e5e5;
    box-sizing: border-box;
  }
  .cube .list{
      display: flex;
      flex:1;
      box-sizing: border-box;
  }
  .cube .list .item{
  
    flex:1;
    border-bottom:1px  solid #e5e5e5;
    border-left:1px  solid #e5e5e5;

    display: flex;
    justify-content:center;
    align-items: center;
    box-sizing: border-box;
  }
  .cube .list .item.active{
    background: #e0edff;
  }
  .cube-selected{
    left: 0;
    top: 0;
    /* width: 300px;
    height: 300px; */
    background:#fff;
    position: absolute;
    z-index: 2;
    border: 1px solid #ebedf0;
    color: #7d7e80;
    box-sizing: border-box;
    cursor: pointer;
  }
  .cube-selected-click:hover .right-delete{
    display: block;
  }
  .cube-selected .right-delete{
    cursor: pointer;
    position: absolute;
    right: -10px;
    top:-10px;
    z-index: 3;
    display: none;
  }
  .cube-selected-click{
    left: 0;
    top: 0;
    border: 1px solid #155bd4;
    color: #155bd4;
    background:#e0edff;
    cursor: default;
    z-index: 3;
  }
  .cube-selected-text{
    font-size: 12px;
    width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    text-align: center;
  }
</style>
<body>
    <div class="cube">
        <!-- <div class="list">
          <div class="item">1</div>
          <div class="item">1</div>
        </div>
        <div class="list">
          <div class="item">1</div>
        </div> -->
    </div>
</body>
<script src="./index.js"></script>
<script>
   (()=>{
      let x = y = 12;
      class Cube {
        list = []
        current = 1
        // 定义横纵坐标(长宽)
        add(item){
          if(!item) return;
          item.id = this.current;
          item.current = true;
          this.list = this.list.map(item => {
            item.current = false 
            return item;
          });
          this.list.push(item);
          this.current++;
          return item;
        }
        remove(id)
        {
          let index = this.list.findIndex(item => item.id == id);
          if(index >=0)
          {
            return this.list.splice(index,1);
          }else{
            return false;
          }
        }
        clear()
        {
          this.list.clear();
        }
        update(id,item = {})
        {
          let index = this.list.findIndex(c_item => c_item.id == id);
          if(index >=0)
          {
            let citem = this.list[index];
            let newitem = Object.assign({},citem,item)
         
            if(newitem.current == true)
            {
              this.list = this.list.map(item => {
                item.current = false 
                return item;
              })
            }
            return this.list.splice(index,1,newitem);
          }else{
            return false;
          }
        }
        init(list = [])
        {
            this.list = list;
        }
      }
     
      class DrawCube {
          constructor(x,y)
          {
              this.x = x;
              this.cube = new Cube();
          }
      }
      
      let cube =  new Cube();




       
      // 绘制几行
      function drawcutelist(x,y)
       {
          let Els =  "";
          
          for (let i = 0; i < x; i++) {
            let itemEl = "";
            for (let yi = 0; yi < y; yi++) {
              itemEl+=`<div data-x="${i}" data-y="${yi}" class="item"></div>`;
            }
            let listEl = `<div class="list">${itemEl}</div>`;
            Els+=listEl;
          } 
          return Els;
       }
       // 挂载元素
       function mountedEl(el,html,isreplace = true)
       {
         let selector = document.querySelector(el);
          if(isreplace)
          {
            selector.innerHTML += html;
          }else{
            selector.appendChild(html)
          }
          let drawArea = [];
          // 添加事件
          selector.addEventListener('click',function(e){
            let target = e.target;
            if(target.className.includes('item'))
            {
              let x = target.getAttribute('data-x');
              let y = target.getAttribute('data-y');
             
              if(drawArea.length == 1)
              {
                let activeels = selector.querySelectorAll('.item.active');
                if(activeels && activeels.length)
                {
                  target1 = [...activeels].pop();
                  x1 = target1.getAttribute('data-x');
                  y1 = target1.getAttribute('data-y');
                  target2 = [...activeels].shift();
                  x2 = target2.getAttribute('data-x');
                  y2 = target2.getAttribute('data-y');
                  drawArea = [[x1,y1],[x2,y2]];
                }
                // target.classList.add("active");
               
                // drawArea.push([x,y]);
                let els = selector.querySelectorAll('.item');
                Array.from(els).map(item => item.classList.remove('active'));
                drawAreaCute(drawArea);
              }else{
                target.classList.add("active");
                drawArea.push([x,y]);
              }
              
            }
          })
          // 区域点坐标
          function areaPointList(startArea,endArea)
          {
              let x0 = ~~startArea[0];
              let y0 = ~~startArea[1];
              let x1 = ~~endArea[0];
              let y1 = ~~endArea[1];
              let maxY = x1 > x0 ? x1 : x0;
              let maxX = y1 > y0 ? y1 : y0;  
              let minY = x1 < x0 ? x1 : x0;
              let minX = y1 < y0 ? y1 : y0; 
              let list = [];
              for (let i = minX; i <= maxX; i++) {
                for (let yi = minY; yi <= maxY; yi++) {
                  list.push(`${i},${yi}`)
                }
              }
              return list;
          }
          // 绘制正方形
          function drawAreaCute(drawArea = []){
              let startdrawArea = (drawArea[0]);
              let enddrawArea = (drawArea[1]);
              let x0 = parseInt(startdrawArea[0]);
              let y0 = parseInt(startdrawArea[1]);
              let x1 = parseInt(enddrawArea[0]);
              let y1 = parseInt(enddrawArea[1]);
              let maxY = x1 > x0 ? x1 : x0;
              let maxX = y1 > y0 ? y1 : y0;  
              let minY = x1 < x0 ? x1 : x0;
              let minX = y1 < y0 ? y1 : y0; 
              let currentCube =  cube.add({
                style:{
                  left:Math.round(minX*cubeItemX),
                  width:Math.round((maxX-minX+1)*cubeItemX),
                  top:Math.round(minY*cubeItemY),
                  height:Math.round((maxY-minY+1)*cubeItemX)
                },
                pointList:[...drawArea],
                className:'cube-selected',
                current:true
              });
              drawArea.length = 0;
              // 清除所有区域选中
              let cubeSelectedEls = selector.querySelectorAll('.cube-selected');
              [...cubeSelectedEls].map(ele => ele.classList.remove('cube-selected-click'));
              // let el = `<div class='cube-selected' style="left:${minX*cubeItemX}px;width:${(maxX-minX+1)*cubeItemX}px;top:${minY*cubeItemX}px;height:${(maxY-minY+1)*cubeItemX}px;"></div>`
              let el = `<div class='cube-selected cube-selected-click cube-selected-v${currentCube.id}' style="left:${currentCube.style.left}px;width:${currentCube.style.width}px;top:${currentCube.style.top}px;height:${currentCube.style.height}px;">
                <div class="right-delete" data-id="${currentCube.id}">删除</div>  
                <div class="cube-selected-text">${currentCube.style.width}x${currentCube.style.height}像素<div>或同等比例</div></div>
              </div>`
         
              selector.innerHTML += el;             
          }
          // 点击换选中区域
          selector.addEventListener('click',function(e){
             let target = e.path.find(el => {
               if(el.classList)
               {
                return (el.classList).contains('cube-selected')
               }else{
                 return false
               }
             }) || e.target;
             let classList = target.classList;
             if(classList.contains('cube-selected')){
               let id = target.getAttribute('data-id');
               // 清除所有区域选中
              let cubeSelectedEls = selector.querySelectorAll('.cube-selected');
              [...cubeSelectedEls].map(ele => ele.classList.remove('cube-selected-click'));
               target.classList.add('cube-selected-click');
               cube.update(id,{
                 current:true
               });
             }
          },true)
          // 绑定删除绘制区域事件
          selector.addEventListener('click',function(e){
             let target = e.target;
             let classList = target.classList;
             if(classList.contains('right-delete')){
               let id = target.getAttribute('data-id');
               let cSelector =selector.querySelector('.cube-selected-v'+id);
               cSelector.remove();
               cube.remove(id);
             }
          })
          selector.addEventListener('mouseleave',function(e){
            if(drawArea.length != 1) return false;
            let els = selector.querySelectorAll('.item'),target = e.target;
            Array.from(els).map(item => item.classList.remove('active'));
            drawArea.length = 0;
          })
          selector.addEventListener('mouseover',function(e){
            if(drawArea.length != 1) return false;
            let els = selector.querySelectorAll('.item'),target = e.target;
            if(target.className.includes('item'))
            {
              
              let x = parseInt(target.getAttribute('data-x'));
              let y = parseInt(target.getAttribute('data-y'));
              let x0 = parseInt(drawArea[0][0]);
              let y0 = parseInt(drawArea[0][1]);
              if(cube.list[0])
              {

                let drawPointlist = [];
                // let list = ([].concat.apply([], ));
                cube.list.forEach(item => {
                  drawPointlist.push(...areaPointList(...item.pointList));
                });
                let drawAreaPointList = areaPointList(drawArea[0],[x,y]);
                
                if([...drawPointlist,...drawAreaPointList].length != ([...(new Set([...drawPointlist,...drawAreaPointList]))].length)){
                   return;
                }
              }
             
              Array.from(els).map(item => item.classList.remove('active'))
              // let points = areaPointList([x,y],[x0,y0])
              let maxX = x > x0 ? x : x0;
              let maxY = y > y0 ? y : y0;  
              let minX = x < x0 ? x : x0;
              let minY = y < y0 ? y : y0;  
              for (let i = parseInt(minX); i <= parseInt(maxX); i++) {
                for (let yi = parseInt(minY); yi <= parseInt(maxY); yi++) {

                  Array.from(selector.querySelectorAll(`.item[data-x='${i}'][data-y='${yi}']`)).map(item => item.classList.add('active'));
                }
              }
            }
          })
       }
       
      let elehtml = drawcutelist(x,y);
      let cuteel = document.querySelector('.cube');
      let cubeItemX  = (cuteel.clientWidth+1)/x;
      let cubeItemY  = (cuteel.clientHeight+1)/y;
       mountedEl(".cube",elehtml);
   })()
</script>
</html>
